const path = require('path')
// 自动生成html入口文件和引用js
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 抽离css
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const toml = require('toml')
const yaml = require('yaml')
const json5 = require('json5')

module.exports = {
    // 入口文件
    // entry: './src/index.js',
    // 多入口文件
    entry: {
        // 相同文件重复打包 冗余
        index: './src/index.js',
        another: './src/another-module.js'
        // 解决：optimization > splitChunks配置
    },
    // entry: {
    //     index: {
    //         import: './src/index.js',
    //         // 允许共享依赖
    //         dependOn: 'shared'
    //     },
    //     another: {
    //         import: './src/another-module.js',
    //         dependOn: 'shared'
    //     },
    //     // 遇到lodash时允许共享
    //     shared: 'lodash'
    // },
    // 输出文件
    output: {
        // 单入口输出文件
        // filename: "bundle.js",
        // 多入口输出文件
        // contenthash防止重新生成文件时浏览器没识别到 使用了缓存文件
        // [xx] 可修改模板字符串
        filename: 'scripts/[name].[contenthash].js',
        // 输入路径 设置为当前目录下的dist
        path: path.resolve(__dirname, './dist'),
        // 清理之前打包的文件，仅保留本次打包的文件
        clean: true,
        // asset模块文件路径 文件名自动生成 扩展名自动生成
        assetModuleFilename: "images/[contenthash][ext]"
    },
    // 模式 开发模式
    mode: 'development',
    // 生产模式
    // mode: 'production',
    // dev设置 精准定位报错代码
    devtool: "inline-source-map",
    // 实例化插件 new 
    plugins: [
        new HtmlWebpackPlugin({
            // 参照模板
            template: "./index.html",
            // 新生成的文件名
            filename: "app.html",
            // script标签嵌入位置
            inject: "body"
        }),
        new MiniCssExtractPlugin({
            // 新生成的文件位于dist/styles/自动生成的文件名
            filename: "styles/[contenthash].css",
        })
    ],
    // 运行时自动更新+编译
    devServer: {
        static: "./dist"
    },
    module: {
        rules: [
            // 匹配png文件 类型为resource 产生单独的文件
            {
                test: /\.png$/,
                type: "asset/resource",
                // 针对不同文件配置，优先级高于output里的assetModuleFilename配置
                generator: {
                    filename: "images/[contenthash][ext]"
                }
            },
            // inline类型导出资源的URI
            {
                test: /\.svg$/,
                type: "asset/inline"
            },
            // source类型导出资源的源代码
            {
                test: /\.txt$/,
                type: "asset/source"
            },
            // asset类型为通用资源类型 自动在resource和inline间选择 
            // 小于8kb视为inline，否则视为resource
            {
                test: /\.jpg$/,
                type: "asset",
                parser: {
                    // 支持修改分界阈值
                    dataUrlCondition: {
                        // 4kb
                        maxSize: 4 * 1024
                    }
                }
            },
            // 解析js里引用到的css / less文件 
            {
                test: /\.(css|less)$/,
                // 执行顺序从后往前
                // use: ['style-loader', 'css-loader', 'less-loader']
                // 抽离css，在dist里生成一个单独的css文件，不能用style-loader（嵌在html页面里）
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 字体资源
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                type: 'asset/resource'
            },
            // 数据文件
            {
                test: /\.(csv|tsv)$/i,
                use: ['csv-loader'],
            },
            {
                // i 不区分大小写
                test: /\.xml$/i,
                use: ['xml-loader'],
            },
            {
                test: /\.toml$/,
                type: 'json',
                parser: {
                    parse: toml.parse
                }
            },
            {
                test: /\.yaml$/,
                type: 'json',
                parser: {
                    parse: yaml.parse
                }
            },
            {
                test: /\.json5$/,
                type: 'json',
                parser: {
                    parse: json5.parse
                }
            },
            // es6+ 转 es5
            {
                test: /\.js$/,
                // node_modules中的js代码不需要转化
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: [
                            [
                                '@babel/plugin-transform-runtime'
                            ]
                        ]
                    }
                }
            }
        ]
    },
    // 优化配置
    optimization: {
        minimizer: [
            new CssMinimizerPlugin()
        ],
        // 内置插件 把公共代码抽离到单独文件 防止重复打包
        splitChunks: {
            // 缓存第三方库
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendors",
                    chunks: 'all'
                }
            }
        }
    }
}
